/*  Novelties: A visual novel programming language based on JavaFX
    Copyright (C) 2008  Hao Xu
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * /
 /*
 * Paragraph.fx
 *
 * Created on Apr 7, 2008, 1:02:07 PM
 */

package avgengine;

import javafx.ui.canvas.*;
import javafx.ui.*;
import java.lang.Thread;

/**
 * @author ertri
 */
class GenericParagraph {
    attribute topacity : Number;
    attribute height : int;
    attribute color: Color;
    attribute font : Font;
    attribute borderColor: Color;
    attribute borderWidth: int;
    operation getVisualNode():Node;
    operation applyStyle(p:GenericParagraph);
    operation setStage(p:Dialog);
    
}
class Style extends GenericParagraph {
}
attribute Style.topacity = -1;
attribute Style.height = -1;
attribute Style.borderWidth = -1;

operation GenericParagraph.applyStyle(p) {
    if(p<>null){
        if(p.topacity<>-1){
            this.topacity = p.topacity;
        }
        if(p.font<>null){
            this.font = p.font;
        }
        if(p.height<>-1){
            this.height = p.height;
        }
        if(p.color<>null){
            this.color = p.color;
        }
        if(p.borderColor<>null){
            this.borderColor = p.borderColor;
        }
        if(p.borderWidth<>-1){
            this.borderWidth = p.borderWidth;
        }
    }
}


class PictureParagraph extends GenericParagraph {
    attribute image : Image;
}
operation PictureParagraph.getVisualNode() {
    return ImageView{
        image : bind image
    };
}

class Paragraph extends GenericParagraph {
    attribute text : String;
    
}

operation Paragraph.getVisualNode() {
    return Text{
        fill: bind color
        stroke: bind borderColor
        strokeWidth: bind borderWidth
        font: bind font
        content : bind text
    };
}

class OptionParagraph extends GenericParagraph {
    attribute default:int;
    attribute options : String *;
    attribute callback : function(i:int);
    attribute hlcolor: Color;
    attribute hlfont : Font;
    attribute hlborderColor: Color;
    attribute hlborderWidth: int;
    attribute disabled : boolean;
    attribute highlight:Dialog;
}

attribute OptionParagraph.disabled = false;

trigger on new OptionParagraph {
    if(hlcolor==null) {
        hlcolor = color;
    }
    if(hlfont ==null) {
        hlfont = font;
    }
    if(hlborderColor==null) {
        hlborderColor = borderColor;
    }
    if(hlborderWidth == null) {
        hlborderWidth = borderWidth;
    }
}

operation OptionParagraph.getVisualNode() {
    var optionNodes = [];
    var anim = Animation{};
    //    insert highlight into optionNodes;
    //    highlight.x=-highlight.pad[0];
    //    highlight.y=height*default-highlight.pad[1];
    //    highlight.dheight = height + 2*highlight.pad[1];
    for(i in [0..sizeof options-1]) {
        var g = Text {
            transform: [translate(0,i*height+(i+1)*highlight.lspace)]
            fill: color
            stroke: borderColor
            strokeWidth: borderWidth
            font: font
            content : bind options[i]
            onMouseEntered: operation(e:CanvasMouseEvent) {
                //overload the semantics of pad and speed
                //                anim.justTranslate(highlight,[-highlight.pad[0],height*i-highlight.pad[1]],highlight.speed);
                //                println("on {i}");
            }
            onMouseExited: operation(e:CanvasMouseEvent) {
                
            }
        };
        insert g into optionNodes;
        var r = Rect {
            transform:[translate(-highlight.pad[0],i*height+(i+1)*highlight.lspace-highlight.pad[1])]
            height : height// + 2*highlight.pad[1]
            width : highlight.dwidth
            opacity: 0.01
            fill: highlight.background
            stroke: highlight.borderColor
            strokeWidth: highlight.borderWidth
            
        };
        r.onMouseEntered = operation(e:CanvasMouseEvent) {
            //overload the semantics of pad and speed
            if(not disabled) {
                println("on {i}");
                anim.justChangeOpacity(r,highlight.opacity,100,highlight.speed);
            }
            
        };
        r.onMouseExited = operation(e:CanvasMouseEvent) {
            if(not disabled) {
                println("off {i}");
                anim.justChangeOpacity(r,0.01,100,highlight.speed);
            }
        };
        r.onMouseClicked = operation(e:CanvasMouseEvent) {
            if(not disabled) {
                var func =this.callback;
                disabled = true;
                func(i);
            }
        };
        insert r into optionNodes;
    }
    return Group {
        content: optionNodes
    };
}

class ButtonParagraph extends PictureParagraph {
    attribute highlight:Dialog;
    attribute onMouseClicked : operation(e:CanvasMouseEvent);
    attribute group: Group;
    operation disable();
    operation enable();
}

operation ButtonParagraph.enable() {
    var anim = Animation{};
    anim.justChangeOpacity(group, topacity, 100, highlight.speed);
    //    group.opacity = topacity;
}
operation ButtonParagraph.disable() {
    var anim = Animation{};
    anim.justChangeOpacity(group, 0, 100, highlight.speed);
    //    group.opacity = 0;
}

operation ButtonParagraph.getVisualNode() {
    
    var optionNodes = [];
    var anim = Animation{};
    var g = ImageView {
        image : bind image
    };
    insert g into optionNodes;
    var r = Rect {
        transform:[translate(-highlight.pad[0],-highlight.pad[1])]
        height : highlight.dheight
        width : highlight.dwidth
        opacity: 0.01
        fill: highlight.background
        stroke: highlight.borderColor
        strokeWidth: highlight.borderWidth
        onMouseClicked: bind onMouseClicked
        
    };
    r.onMouseEntered = operation(e:CanvasMouseEvent) {
        //overload the semantics of pad and speed
        anim.justChangeOpacity(r,highlight.opacity,100,highlight.speed);
        
    };
    r.onMouseExited = operation(e:CanvasMouseEvent) {
        anim.justChangeOpacity(r,0.01,100,highlight.speed);
        
    };
    //    r.onMouseClicked = operation(e:CanvasMouseEvent) {
    //        var func =this.callback;
    //        func();
    //    };
    insert r into optionNodes;
    group = Group {
        opacity: topacity
        content: optionNodes
    };
    return group;
}

class SpriteParagraph extends GenericParagraph {
    attribute sprite:Sprite;
    attribute x : int;
    attribute y : int;
}

operation SpriteParagraph.getVisualNode() {
    return sprite.group;
    
}

operation SpriteParagraph.setStage(p) {
    sprite.stage = p;
}